﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Text;
using System.Windows;
using Microsoft.Practices.Prism.Commands;
using ParaEditor.Common;
using ParaEditor.DAO;
using ParaEditor.DAO.ParaDAO;
using ParaEditor.Desktop.Helper;
using ParaEditor.Desktop.Interfaces;
using ParaEditor.Domain.Entities;
using ParaEditor.DomainSource.Entities;
using ParaEditor.Infrastructure;

namespace ParaEditor.Desktop.ViewModel
{
    [Export(typeof(IPara4030ViewModel))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class Para4030ViewModel : ViewModelBase, IPara4030ViewModel
    {
        private int currentVersion;
        public int CurrentVersion
        {
            get
            {
                return this.currentVersion;
            }
            set
            {
                this.currentVersion = value;
                this.RaisePropertyChangedEvent("CurrentVersion");
            }
        }

        private int effectVersion;
        public int EffectVersion
        {
            get
            {
                return this.effectVersion;
            }
            set
            {
                this.effectVersion = value;
                this.RaisePropertyChangedEvent("EffectVersion");
            }
        }

        private int progress1;
        public int Progress1
        {
            get
            {
                return this.progress1;
            }
            set
            {
                this.progress1 = value;
                this.RaisePropertyChangedEvent("Progress1");
            }
        }

        private int progress2;
        public int Progress2
        {
            get
            {
                return this.progress2;
            }
            set
            {
                this.progress2 = value;
                this.RaisePropertyChangedEvent("Progress2");
            }
        }

        private Visibility progressVisibility;
        public Visibility ProgressVisibility
        {
            get
            {
                return this.progressVisibility;
            }
            set
            {
                this.progressVisibility = value;
                this.RaisePropertyChangedEvent("ProgressVisibility");
            }
        }

        private string tips1;
        public string Tips1
        {
            get
            {
                return this.tips1;
            }
            set
            {
                this.tips1 = value;
                this.RaisePropertyChangedEvent("Tips1");
            }
        }

        private string tips2;
        public string Tips2
        {
            get
            {
                return this.tips2;
            }
            set
            {
                this.tips2 = value;
                this.RaisePropertyChangedEvent("Tips2");
            }
        }

        private string timeSpan;
        public string TimeSpan
        {
            get
            {
                return this.timeSpan;
            }
            set
            {
                this.timeSpan = value;
                this.RaisePropertyChangedEvent("TimeSpan");
            }
        }

        private bool canClick;
        public bool CanClick
        {
            get
            {
                return this.canClick;
            }
            set
            {
                this.canClick = value;
                this.RaisePropertyChangedEvent("CanClick");
            }
        }


        public DelegateCommand ImportCommand { get; private set; }
        public DelegateCommand SubVersionCommand { get; private set; }
        public DelegateCommand AddVersionCommand { get; private set; }


        private BackgroundWorker worker;
        private BackgroundWorker workerReportProgress;


        private Para4030DAO paramDAO;
        private SourceBaseDAO sourceDAO;

        private StringBuilder sbTips = new StringBuilder();

        [ImportingConstructor]
        public Para4030ViewModel()
        {
            CanClick = true;
            paramDAO = new Para4030DAO();
            sourceDAO = new SourceBaseDAO();
            this.ProgressVisibility = Visibility.Hidden;

            this.worker = new BackgroundWorker();
            this.worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            this.worker.DoWork +=new DoWorkEventHandler(worker_DoWork);
            this.worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            this.worker.WorkerReportsProgress = true;


            
            this.ImportCommand = new DelegateCommand(this.Import);
            this.SubVersionCommand = new DelegateCommand(this.SubVersion);
            this.AddVersionCommand = new DelegateCommand(this.AddVersion);

            this.CurrentVersion = paramDAO.GetMaxID();
            this.EffectVersion = this.CurrentVersion + 1;

            this.Tips1 = "等待操作...\r\n";
        }

        private void SubVersion()
        {
            this.EffectVersion -= 1;
        }

        private void AddVersion()
        {
            this.EffectVersion += 1;
        }

        private void Import()
        {
            this.ProgressVisibility = Visibility.Visible;
            worker.RunWorkerAsync();
        }

        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.Progress1 = e.ProgressPercentage;
        }

        

        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            TimeSpan toNow;
            CanClick = false;
            workerReportProgress = sender as BackgroundWorker;
            StringBuilder sb = new StringBuilder();
            Tips1 += "正在抽取数据...请稍等\r\n";
            IList<SubRoad> subRoadList = sourceDAO.GetCurrenSubRoad();
            Tips1 += "抽取成功\r\n";
            
            int maxid = this.EffectVersion;
            if (this.EffectVersion <= this.CurrentVersion)
            {
                //删除当前版本
                Tips1 += "正在删除版本[";
                Tips1 += this.CurrentVersion;
                Tips1 += "]的数据...\r\n";
                ResultValue rValue = paramDAO.DelParamByVersion(this.CurrentVersion);
                if (rValue.Code != 0)
                {
                    Microsoft.Windows.Controls.MessageBox.Show("重新生成所选版本时发生错误!" + rValue.Msg);
                    return;
                }
                Tips1 += "删除完成!\r\n";
            }
            
            Tips1 += "正在转换数据...请稍等\r\n";
            IList<Para4030> paramList = DomainConvert.ConvertToPara4030(subRoadList, this.EffectVersion);
            Tips1 += "转换完成\r\n";
            Tips1 += "开始导入数据...\r\n";
            int count = paramList.Count;
            int mod = count / 100;
            int yu = count - mod * 100;
            int i = 1;
            double percent = 0;
            long startTimeSpan = DateTime.Now.Ticks;
            long currentTimeSpan = 0;
            for (int j = 0;j < 101 ;)
            {
                for (; i <= count; i++)
                {
                    paramDAO.CreateObjectNonFlushSession(paramList[i - 1]);
                    if (i % 1277 == 0)
                    {
                        paramDAO.FlushSession();
                        currentTimeSpan = DateTime.Now.Ticks;
                        toNow = new TimeSpan((currentTimeSpan - startTimeSpan) / i);
                        sb.Append("剩余");
                        sb.Append(Math.Round(toNow.TotalSeconds * (count - i) / 60,2));
                        sb.Append("分钟");
                        this.TimeSpan = sb.ToString();
                        sb.Clear();
                    }
                    percent = i / count;
                    sb.Append(i);
                    sb.Append(" of ");
                    sb.Append(count);
                    //sb.Append("    完成度:");
                    //sb.Append(percent);
                    //sb.Append("%");
                    Tips2 = sb.ToString();
                    sb.Clear();
                    if (i >= mod * j + yu)
                    {
                        //break;
                        j++;
                        paramDAO.FlushSession();
                        workerReportProgress.ReportProgress(j);
                    }
                }
                //workerReportProgress.ReportProgress(j);
            }
            paramDAO.FlushSession();
            this.TimeSpan = "剩余0分钟";
            Tips1 += "完成!\r\n";
        }

        
        void worker_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
        {
            this.ProgressVisibility = Visibility.Hidden;
            CanClick = true;
        }

    }
}
